<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>
<body >
  <div id="div" style="height: 10000px;width: 100px;background-color: aquamarine;"></div>
  <script>

    /**
     * 防抖debounce：
            立即执行：即多次触发事件，第一次会立即执行函数，之后在设定wait事件内触犯的事件无效，不会执行。
            非立即执行函数： 多次触发事件，只会在最后一次触发事件后等待设定的wait时间结束时执行一次。

     * 功能：支持传参,支持使用this(绑定事件节点)，
     * 效果：delay时间内 连续触发 同一事件，会延迟delay时间执行，且只会执行一次
     * 思路：触发事件设置一个200ms延迟，
     *      200ms内若 再次触发 事件，则 重置计时 ，重新开始计时200ms
     *      200ms内若 没有 再次触发事件，则 执行事件 
     * 
     * fn：需防抖函数
     * delay：毫秒，防抖期限值
     * immediate: true 立即执行, false 不立即执行
     * args:剩余参数，传递给函数
     **/
    function debounce(fn, delay, immediate, ...args){
      // console.log(this)
      // console.log(arguments)
      let timer = null  // 借助闭包
      return function(){
        
        // timer存在，消除定时器
        if(timer){ clearTimeout(timer) }

        // 是否立即执行
        if(immediate){
          var callNow = !timer
          timer = setTimeout(() => {
            timer = null
          }, delay);
          if(callNow) fn.call(this, ...args)
        }else{
          timer = setTimeout(()=>{
            fn.call(this, ...args)
          }, delay);
        }
        
      }
    }

    /**
     * 节流throttle：事件在连续触发时，间隔一段时间执行一次
     * 
     * 效果：不断触发事件，一定时间间隔也能触发一次事件
     * 思路：设置状态位，表示是否
     */
    function throttle(fn,delay,...args){
      let flag = true // 状态位： true:可以执行，false：不能执行
      return function(){
        if(flag){
          flag = false
          setTimeout(() => {
            fn(...args)
            flag = true
          }, delay)
        }
      }
    }
    // window.addEventListener("scroll",showTop)   // 没有防抖节流
    // let div = document.querySelector("#div")
    document.addEventListener("scroll",debounce(showTop,200,true,"hhhh"))  // 使用防抖
    // document.addEventListener("scroll",debounce2(showTop,200,"hhhh"))  // 使用防抖
    // window.addEventListener("scroll",throttle(showTop,500,"hhhh"))  // 使用节流
    function showTop(msg){
      console.log(this)
      var scroll = document.body.scrollTop || document.documentElement.scrollTop
      console.log(scroll+msg)
    }
  </script>
</body>
</html>